-- SV (Saved Var)
-----------------
ITA_SV_blackListedPlayers = {}
ITA_SV_blackListedGuilds = {}
ITA_SV_config = {}

-- ...
------------------
--local addonName, IgnoreThemAll = ...

-- Global namespace var
----------------------------
IgnoreThemAll = {}

IgnoreThemAll.timeSinceLastReply = nil
IgnoreThemAll.details = {	name = "IgnoreThemAll",
							frame = "ITA_mainFrame",
							optionsframe = "ITA_configFrame" }
IgnoreThemAll.variablesLoaded = false
IgnoreThemAll.realm = GetRealmName()

-- LV (Local Var)
-----------------
local wholib = LibStub:GetLibrary('LibWho-2.0'):Library()
local timeToUpdateDB = nil

-- default config values
------------------------
local onDefault = true
local filterChannelDefault = false
local filterSayDefault = false
local filterYellDefault = false
local filterWhisperDefault = true
local whisperNotificationDefault = true
local autoReplyDefault = false
local autoReplyMsgDefault = "PLAYER is ignoring you, because you are a member of GUILD"


-- create main frame
--------------------

local frameName = "ITA_mainFrame"
local frame = CreateFrame("Frame", frameName)

-- register events
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("VARIABLES_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")

-- set scripts
frame:SetScript("OnEvent", function (self, event, ...)
	if (event == "PLAYER_LOGIN") then
		SLASH_IGNORE_THEM_ALL_CMD1 = "/ita"
		SLASH_IGNORE_THEM_ALL_CMD2 = "/ignorethemall"
		SlashCmdList["IGNORE_THEM_ALL_CMD"] = IgnoreThemAll.Command
		IgnoreThemAll.UpdateFilter()
	end
	if (event == "PLAYER_ENTERING_WORLD") then
        timeToUpdateDB = 30.0
    end
	if (event == "VARIABLES_LOADED") then
		IgnoreThemAll.VariablesLoaded()
	end
end)

frame:SetScript("OnUpdate", function (self, elapsed)
	-- 0.1 sec delay to avoid double outputs/replies
    if (IgnoreThemAll.timeSinceLastReply ~= nil) then
        IgnoreThemAll.timeSinceLastReply = IgnoreThemAll.timeSinceLastReply + elapsed
        if (IgnoreThemAll.timeSinceLastReply >= 0.1) then 
			IgnoreThemAll.timeSinceLastReply = nil
		end
    end
	
	-- auto update player list
    timeToUpdateDB = timeToUpdateDB + elapsed
    if (timeToUpdateDB >= 300.0) then
        IgnoreThemAll.UpdateList()
        timeToUpdateDB = 0
    end
end)

function IgnoreThemAll.AddCategory(configpanel)
	configpanel = configpanel
	configpanel.name = "IgnoreThemAll " .. GetAddOnMetadata("IgnoreThemAll", "Version")
	configpanel.okay =  function(self) IgnoreThemAll.ConfigChange() end
	configpanel.default = function(self) IgnoreThemAll.SetDefaults() end
    --configpanel.cancel = 
	
    -- Add the panel to the Interface Options
    --InterfaceOptions_AddCategory(configpanel)
end
     	

-- functions
------------

function IgnoreThemAll.VariablesLoaded()
	if ( not ITA_SV_config[IgnoreThemAll.realm] ) then 
		ITA_SV_config[IgnoreThemAll.realm] = {}
	end
		
	-- load each option, set default if not there
	if ( ITA_SV_config[IgnoreThemAll.realm].on == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].on = onDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].filterChannel == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].filterChannel = filterChannelDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].filterSay == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].filterSay = filterSayDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].filterYell == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].filterYell = filterYellDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].filterWhisper == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].filterWhisper = filterWhisperDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].whisperNotification == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].whisperNotification = whisperNotificationDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].autoReply == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].autoReply = autoReplyDefault
	end
	if ( ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg == nil ) then 
		ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg = autoReplyMsgDefault
	end
		
	-- record that we have been loaded
	IgnoreThemAll.variablesLoaded = true;
	-- we know other addons have been "loaded" now
	   -- optional dependance on myAddOns, leads to our config panel
	if( myAddOnsFrame_Register ) then
		myAddOnsFrame_Register( IgnoreThemAll.details )
	end
	-- configuration might have changed
	IgnoreThemAll.UpdateConfig()
end

function IgnoreThemAll.ConfigChange()
	
	if (IgnoreThemAll.variablesLoaded) then
	
		if(CheckButton_WhisperNotification:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].whisperNotification = true
		else
			ITA_SV_config[IgnoreThemAll.realm].whisperNotification = false
		end
			
		if(CheckButton_FilterWhisper:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].filterWhisper = true
		else 
			ITA_SV_config[IgnoreThemAll.realm].filterWhisper = false
		end
		
		if(CheckButton_FilterChannel:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].filterChannel = true
		else
			ITA_SV_config[IgnoreThemAll.realm].filterChannel = false
		end
		
		if(CheckButton_FilterSay:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].filterSay = true
		else
			ITA_SV_config[IgnoreThemAll.realm].filterSay = false
		end
		
		if(CheckButton_FilterYell:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].filterYell = true
		else
			ITA_SV_config[IgnoreThemAll.realm].filterYell = false
		end
		
		if(CheckButton_AutoReply:GetChecked()) then 
			ITA_SV_config[IgnoreThemAll.realm].autoReply = true
		else
			ITA_SV_config[IgnoreThemAll.realm].autoReply = false
		end
		
	else
		ITA_ConfigFrame:Hide()
	end

	IgnoreThemAll.UpdateFilter()
end

function IgnoreThemAll.UpdateAutoReplyMsg()
	ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg = EditBox_AutoReplyMsg:GetText()
	FontString_AutoReplyMsg:SetText(ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg)
	EditBox_AutoReplyMsg:ClearFocus()
end

--
--------------------------
function IgnoreThemAll.UpdateFilter()

	if( ITA_SV_config[IgnoreThemAll.realm].filterWhisper) then
		ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", IgnoreThemAll.ChatFilter)
		ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", IgnoreThemAll.ChatFilter)
	else
		ChatFrame_RemoveMessageEventFilter("CHAT_MSG_WHISPER", IgnoreThemAll.ChatFilter)
		ChatFrame_RemoveMessageEventFilter("CHAT_MSG_WHISPER_INFORM", IgnoreThemAll.ChatFilter)
	end

	if( ITA_SV_config[IgnoreThemAll.realm].filterChannel) then
		 ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", IgnoreThemAll.ChatFilter)
	else
		ChatFrame_RemoveMessageEventFilter("CHAT_MSG_CHANNEL", IgnoreThemAll.ChatFilter)
	end

	if( ITA_SV_config[IgnoreThemAll.realm].filterSay) then
		 ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY", IgnoreThemAll.ChatFilter)
	else
		ChatFrame_RemoveMessageEventFilter("CHAT_MSG_SAY", IgnoreThemAll.ChatFilter)
	end

	if( ITA_SV_config[IgnoreThemAll.realm].filterYell) then
		 ChatFrame_AddMessageEventFilter("CHAT_MSG_YELL", IgnoreThemAll.ChatFilter)
	else
		ChatFrame_RemoveMessageEventFilter("CHAT_MSG_YELL", IgnoreThemAll.ChatFilter)
	end
	
end

function IgnoreThemAll.Config()
	IgnoreThemAll.UpdateConfig()
	--IgnoreThemAll.openConfig()
	ITA_configFrame:Show()
end

function IgnoreThemAll.UpdateConfig() 
	
	CheckButton_WhisperNotification:SetChecked(ITA_SV_config[IgnoreThemAll.realm].whisperNotification)
	CheckButton_FilterWhisper:SetChecked(ITA_SV_config[IgnoreThemAll.realm].filterWhisper)
	CheckButton_FilterChannel:SetChecked(ITA_SV_config[IgnoreThemAll.realm].filterChannel)
	CheckButton_FilterSay:SetChecked(ITA_SV_config[IgnoreThemAll.realm].filterSay)
	CheckButton_FilterYell:SetChecked(ITA_SV_config[IgnoreThemAll.realm].filterYell )
	CheckButton_AutoReply:SetChecked(ITA_SV_config[IgnoreThemAll.realm].autoReply)

	FontString_AutoReplyMsg:SetText(ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg)
end

function IgnoreThemAll.showAutoReplyMsg()
	return ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg 
end

function IgnoreThemAll.SetDefaults() 
	ITA_SV_config[IgnoreThemAll.realm].on = onDefault
	
	ITA_SV_config[IgnoreThemAll.realm].whisperNotification = whisperNotificationDefault
	CheckButton_WhisperNotification:SetChecked(whisperNotificationDefault)

	ITA_SV_config[IgnoreThemAll.realm].filterWhisper = filterWhisperDefault
	CheckButton_FilterWhisper:SetChecked(filterWhisperDefault)

	ITA_SV_config[IgnoreThemAll.realm].filterChannel = filterChannelDefault
	CheckButton_FilterChannel:SetChecked(filterChannelDefault)

	ITA_SV_config[IgnoreThemAll.realm].filterSay = filterSayDefault
	CheckButton_FilterSay:SetChecked(filterSayDefault)

	ITA_SV_config[IgnoreThemAll.realm].filterYell = filterYellDefault
	CheckButton_FilterYell:SetChecked(filterYellDefault)
	
	ITA_SV_config[IgnoreThemAll.realm].autoReply = autoReplyDefault
	CheckButton_AutoReply:SetChecked(autoReplyDefault)

	ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg = autoReplyMsgDefault
	FontString_AutoReplyMsg:SetText(autoReplyMsgDefault)

end

function IgnoreThemAll.Command(msg)
    local arguments = utils.strsplit(" ", msg)
    local cmd = arguments[1]

    local i
    local pending = {}
    for i = 2, #arguments do
        table.insert(pending, arguments[i])
    end
	
    if (cmd == "add") then   
        local guild = utils.strjoin(" ", pending)
        IgnoreThemAll.AddGuild(guild)
    elseif (cmd == "remove") then
        local guild = utils.strjoin(" ", pending)
        IgnoreThemAll.RemoveGuild(guild)
    elseif (cmd == "list") then
        IgnoreThemAll.ShowList()
    elseif (cmd == "update") then
        IgnoreThemAll.UpdateList()
	elseif (cmd == "reset") then
	    IgnoreThemAll.Reset()
	elseif (cmd == "config") then
		IgnoreThemAll.Config()
    else
        DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll - chat commands:")
        DEFAULT_CHAT_FRAME:AddMessage("   add *guildname* - add guild to blacklist")
        DEFAULT_CHAT_FRAME:AddMessage("   remove *guildname* - removes guild from blacklist")
        DEFAULT_CHAT_FRAME:AddMessage("   update - update the player database from black listed guilds")
        DEFAULT_CHAT_FRAME:AddMessage("   list - show the currently ignored guilds and number of characters ignored per guild")
		DEFAULT_CHAT_FRAME:AddMessage("   config - open the config window")
		DEFAULT_CHAT_FRAME:AddMessage("   reset - clear all ignored guilds/players")
    end
end

-- reset blacklists
function IgnoreThemAll.Reset()
  wipe(ITA_SV_blackListedGuilds)
  wipe(ITA_SV_blackListedPlayers)
  DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Reset - deleted all guilds from blacklist") 
end

-- add guild to the blacklist
function IgnoreThemAll.AddGuild(guild)
    if (ITA_SV_blackListedGuilds[guild] == nil) then
        ITA_SV_blackListedGuilds[guild] = {}
		DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Add - guild "..guild.." added to blacklist")
        IgnoreThemAll.UpdateList()
	else 
		DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Add - guild "..guild.." already on blacklist") 
	end
end

-- remove guild from blacklist
function IgnoreThemAll.RemoveGuild(guild)
    local players = ITA_SV_blackListedGuilds[guild]
    if (players ~= nil) then
        for k, v in pairs(players) do
            ITA_SV_blackListedPlayers[k] = nil
        end
        ITA_SV_blackListedGuilds[guild] = nil
		DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Remove - guild "..guild.." removed from blacklist") 
    else DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Remove - guild "..guild.." is not on blacklist")  end
end

-- issues a who query for each ignored guild and add new players to blacklist
function IgnoreThemAll.UpdateList()
    for guild, v in pairs(ITA_SV_blackListedGuilds) do
        wholib:Who('g-"' .. guild .. '"', { queue = wholib.WHOLIB_QUEUE_SCANNING, callback = IgnoreThemAll.WhoResults })
    end
end

function IgnoreThemAll.WhoResults(query, results, complete)
    local numAdded = 0
	
    for k, v in pairs(results) do
        local players = ITA_SV_blackListedGuilds[v.Guild]	
        if(players and players[v.Name] == nil or ITA_SV_blackListedPlayers[v.Name] == nil) then
            players[v.Name] = true
            ITA_SV_blackListedPlayers[v.Name] = true
            numAdded = numAdded + 1
        end
    end

    if (numAdded > 0) then
        local sentenceEnd = "s."
        if numAdded == 1 then
            sentenceEnd = "."
        end    
        DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Added " .. numAdded .. " player" .. sentenceEnd)
    end
end


function IgnoreThemAll.ShowList()
    local numGuilds = utils.numEntrysInTable(ITA_SV_blackListedGuilds)
    if (numGuilds == 0) then
        DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: There are no guilds on your blacklist")
        return
    end

    DEFAULT_CHAT_FRAME:AddMessage("IgnoreThemAll: Currently ignoring " .. utils.numEntrysInTable(ITA_SV_blackListedPlayers) .. " total players")
    for guild, players in pairs(ITA_SV_blackListedGuilds) do
        count = utils.numEntrysInTable(players)
        DEFAULT_CHAT_FRAME:AddMessage("  <" .. guild .. "> - " .. count .. " players")
    end
end

-- filter out any messages sent by ignored people
function IgnoreThemAll.ChatFilter(self, event, arg1, arg2, ...)
	--arg2 = player name
    if (ITA_SV_blackListedPlayers[arg2]) then
        if (event == "CHAT_MSG_WHISPER") then
            -- check to avoid double replies/outputs
            if (IgnoreThemAll.timeSinceLastReply == nil) then
			
                local playerGuild = ""
                for guild, players in pairs(ITA_SV_blackListedGuilds) do
                    if (players[arg2] ~= nil) then
                        playerGuild = guild
                    end
                end

                local message = ITA_SV_config[IgnoreThemAll.realm].autoReplyMsg

				message = string.gsub(message, "GUILD", "<"..playerGuild..">")
				message = string.gsub(message, "PLAYER", UnitName("player") )

                -- auto reply with reason for ignoring that person
				if (ITA_SV_config[IgnoreThemAll.realm].autoReply) then
					SendChatMessage(message, "WHISPER", nil, arg2)
				end

				if (ITA_SV_config[IgnoreThemAll.realm].whisperNotification) then
					print("IgnoreThemAll: Whisper blocked from "..arg2.." <"..playerGuild..">")
				end

				IgnoreThemAll.timeSinceLastReply = 0.0

            end
			return true, ...
        end
		return true, ...
    end
    return false
end
